import { AppConsts } from '@shared/AppConsts';
import { Observable, Observer } from 'rxjs';
import { AppLocalizationService } from '@app/shared/common/localization/app-localization.service';
import { AppNotifyService } from '@shared/utils/service/app-notify.service';
import { FileItem, FileUploader, FileUploaderOptions } from 'ng2-file-upload';
import { IAjaxResponse } from 'abp-ng2-module';

export class FileUploadHelper {

    static createUploader(url: string, 
        getToken:()=> string,
        success: (result: any) => void,
        error?: (result: any) => void,
        onBuildItemForm?: (form: any)=> void): FileUploader {
        const uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + url });

        uploader.onAfterAddingFile = (file) => {
            file.withCredentials = false;
        };

        uploader.onSuccessItem = (item, response, status) => {
            const ajaxResponse = <IAjaxResponse>JSON.parse(response);
            if (ajaxResponse.success) {
                if (success) {
                    success(ajaxResponse.result);
                }
            } else if (ajaxResponse.error) {
                if (error) {
                    error(ajaxResponse.error);
                }
            }else{
                if (success) {
                    success(ajaxResponse.result);
                }
            }
        };

        uploader.onErrorItem = (fileItem, response, status, headers) => {
            const ajaxResponse = <IAjaxResponse>JSON.parse(response);
            if (error) {
                error(ajaxResponse.error);
            }
        };

        if(onBuildItemForm){
            uploader.onBuildItemForm = (fileItem: FileItem, form: any) => {
                onBuildItemForm(form);
            };
        }

        let token = getToken();
        const uploaderOptions: FileUploaderOptions = {};
        uploaderOptions.authToken = 'Bearer ' + token;
        uploaderOptions.removeAfterUpload = true;
        uploader.setOptions(uploaderOptions);
        return uploader;
    }


    static getIcon(exName: string): string {
        if (!exName) {return null;}
        exName = exName.toLowerCase(); 
        // svg 不能预览
        if (!this.isImage(exName) && !this.isSvg(exName)) {
            if (exName === "zip" || exName === "rar" || exName === "tar"
                || exName === "gz" || exName === "gzip" || exName === "7z") {
                return "bi bi-file-earmark-zip";
            } else if (exName === "pdf") {
                return "bi bi-file-earmark-pdf";

            } else if (exName === "doc" || exName === "docx") {
                return "bi bi-file-earmark-word";

            } else if (exName === "xls" || exName === "xlsx") {
                return "bi bi-file-earmark-excel";

            } else if (exName === "ppt" || exName === "pptx") {
                return "bi bi-file-earmark-ppt";
            } else if (exName === "txt" || exName === "jnt") {
                return "bi bi-file-earmark-text";

            } else if (exName === "wav" || exName === "mp3" || exName === "ram"
                || exName === "wma" || exName === "mmf" || exName === "aac") {
                return "bi bi-file-earmark-music";

            } else {
                return "bi bi-file-earmark";
            }
        }
        return null;
    }

    /**
     * 
     * @param fileName
     * @param allowedExNames  jpg|jpeg|gif|bmp|png
     */
    static checkExName(fileName:string, allowedExNames: string): boolean{
        let exName = this.getExName(fileName);

        if ((allowedExNames + '|').indexOf(exName + "|") != -1) {
            return true;
        }

        return false;
    }

    static checkMaxSize(fileSize: number, allowedMaxSize: number): boolean {
        let tempSize = Math.round(fileSize / (1024 * 1024) * 100) / 100;
        if (allowedMaxSize >= tempSize) {
            return true;
        }

        return false;
    }

    static getFileSize(fileSize: number): string {
        let tempSize = Math.round(fileSize / 1024 * 100) / 100;
        if (tempSize > 1024) {
            tempSize =  Math.round(tempSize / 1024 * 100) / 100;
            if(tempSize > 1024){
                return (Math.round(tempSize / 1024 * 100) / 100) + "MB";
            }else{
                return tempSize + "MB";
            }
        }
        else {
            return tempSize + "KB";
        }
    }

    static getUrl(fileUrl: string): string {
        return AppConsts.remoteServiceFileBaseUrl + fileUrl;
    }

    static getDownUrl(exName: string, fileUrl: string): string {
        if (!exName) {
            return '';
        }
        if(abp.custom.aliyunOss){
            return AppConsts.remoteServiceFileBaseUrl  + fileUrl;
        }
        if (exName === 'pdf' || exName === 'mp4') {
            return AppConsts.remoteServiceFileBaseUrl  + fileUrl;
        }

        return AppConsts.remoteServiceBaseUrl + '/Utils/Down?myfile=' + '/mtsc/uploads/' + fileUrl;
    }

    static getSmallUrl(fileUrl: string, w: number, h: number) {
        let exName = this.getExName(fileUrl);
        if (this.isImage(exName)){
            return AppConsts.remoteServiceFileBaseUrl + fileUrl;
            //return AppConsts.remoteServiceBaseUrl + '/Utils/Zoomin?w=' + w + '&h=' + h +'&mode=3&path=' + fileUrl;
        }
        return AppConsts.remoteServiceFileBaseUrl + fileUrl;
    }

    static isSvg(exName: string){
        return exName === "svg";
    }
    static isImage(exName: string){
        return "|jpg|jpeg|gif|bmp|png|".indexOf( "|"+ exName + "|") > -1;
    }

    static getRelativeUrl(fileUrl: string){
        if(!fileUrl){
            return "";
        }
        return fileUrl.replace(AppConsts.remoteServiceBaseUrl ,'');
    }

    //TODO Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'.
    static getBase64(file: any) {
        return new Observable((observer: Observer<string>) => {
            const reader = new FileReader();
            reader.onload = (e) => {
                observer.next(e.target.result as string);
            };
            reader.readAsDataURL(file);
        });
    }


    static getExName(fileUrl:string) {
        if(!fileUrl){
            return '';
        }
        let index1 = fileUrl.lastIndexOf(".");
        if(index1 < 0){
            return '';
        }

        return fileUrl.substring(index1 + 1).toLowerCase();
    }

    static check(fileName: string, allowedExNames: string, fileSize: number, allowedMaxSize: number,
        notify: AppNotifyService,
        appLocalizationService: AppLocalizationService    ) {
        if (!FileUploadHelper.checkExName(fileName, allowedExNames)) {
            let exNameArr = allowedExNames.split('|');
            notify.error(fileName + '：' + appLocalizationService.l('File_Invalid_Type_Error', exNameArr.join('、')));
            return true;
        }

        if (!FileUploadHelper.checkMaxSize(fileSize, allowedMaxSize)) {
            let tempSize = Math.round(fileSize / (1024 * 1024) * 100) / 100;
            notify.error(fileName + '：' + appLocalizationService.l('File_SizeLimit_Error', allowedMaxSize, tempSize));
            return true;
        }

        return false;
    }

    static newGuid(): string {
        let s = [];
        let hexDigits = "0123456789abcdef";
        let temp: number;
        for (let i = 0; i < 36; i++) {
            let temp= Math.floor(Math.random() * 0x10);
            s[i] = hexDigits.substring(temp, temp + 1);
        }
        s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        temp = (s[19] & 0x3) | 0x8;
        s[19] = hexDigits.substring(temp, temp + 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";

        var uuid_str = s.join("");
        return uuid_str;
    }

    static randomId(): string {
        let s = [];
        let hexDigits = "0123456789abcdef";
        let temp: number;
        for (let i = 0; i < 18; i++) {
            let temp= Math.floor(Math.random() * 0x10);
            s[i] = hexDigits.substring(temp, temp + 1);
        }

        return s.join("");
    }
}
